package com.itheima.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import javax.xml.transform.Result;

//通知类，告诉spring在增强的前后需要做什么事

/*<bean id="advice" class="com.itheima.aop.Advice"/>*/
@Component
@Aspect
public class Advice {

    /*<aop:pointcut id="pt" expression="execution(* com.itheima.service.impl.StudentServiceImpl.*(..))"/>
        <aop:aspect ref="advice">
            <!--<aop:before method="before" pointcut-ref="pt"/>
            <aop:after-returning method="afterReturn" pointcut-ref="pt"/>
            <aop:after-throwing method="afterThrowable" pointcut-ref="pt"/>
            <aop:after method="after" pointcut-ref="pt"/>-->
            <aop:around method="around" pointcut-ref="pt"/>
        </aop:aspect>*/
    @Pointcut("execution(* com.itheima.service.impl.StudentServiceImpl.*(..))")
    public void pt(){}

    @Before("pt()")
    public void before(){
        //前置通知：开启事务
        System.out.println("前置通知：开启事务");
    }

    @AfterReturning("pt()")
    public void afterReturn(){
        //后置通知：提交事务
        System.out.println("后置通知：提交事务");
    }

    @AfterThrowing("pt()")
    public void afterThrowable(){
        //异常通知：回滚事务
        System.out.println("异常通知：回滚事务");
    }

    @After("pt()")
    public void after(){
        //最终通知：释放资源
        System.out.println("最终通知：释放资源");
    }

    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp){
        Object result = null;
        try {
            before();
            //执行目标方法，相当于动态代理中的result = method.invoke(...)
            result = pjp.proceed();
            afterReturn();
        } catch (Throwable throwable) {
            afterThrowable();
        } finally {
            after();
        }
        return result;
    }
}
